package com.question.business.post.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.question.business.dept.service.IDeptPostService;
import com.question.business.post.entity.Post;
import com.question.business.post.mapper.PostMapper;
import com.question.business.post.model.ao.*;
import com.question.business.post.model.vo.*;
import com.question.business.post.service.IPostService;
import com.question.business.user.service.IUserPostService;
import com.question.common.constants.NumberConstants;
import com.question.common.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 岗位服务实现类
 *
 * @author star
 * @since 2023-09-13
 */
@Slf4j
@Service
@AllArgsConstructor
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements IPostService {

    private final IDeptPostService deptPostService;

    private final IUserPostService userPostService;

    /**
     * 岗位分页查询
     *
     * @param ao 请求参数
     * @return Page<PostVO> 响应参数
     */
    @Override
    public Page<PostVO> queryPostPage(PostPageAO ao) {
        return baseMapper.queryPostPage(ao.createPage(), ao);
    }

    /**
     * 岗位明细查询
     *
     * @param id 岗位ID
     * @return PostDetailVO 响应参数
     */
    @Override
    public PostDetailVO queryPostDetail(String id) {
        Post entity = super.getById(id);
        if (Objects.nonNull(entity)) {
            PostDetailVO vo = new PostDetailVO();
            BeanUtils.copyProperties(entity, vo);
            vo.setDeptIds(deptPostService.queryDeptByPostId(vo.getId()));
            vo.setUserIds(userPostService.queryUserByPostId(vo.getId()));
            return vo;
        }
        return null;
    }

    /**
     * 岗位新增数据
     *
     * @param ao 请求参数
     * @return PostAddVO 响应参数
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public PostAddVO addPost(PostAddAO ao) {
        if (queryNameExist(ao.getPostName())) {
            throw new BusinessException("岗位名称已存在");
        }
        Post entity = new Post();
        BeanUtils.copyProperties(ao, entity);
        super.save(entity);
        deptPostService.addPostDept(entity.getId(), ao.getDeptIds());
        userPostService.addPostUser(entity.getId(), ao.getUserIds());
        PostAddVO vo = new PostAddVO();
        vo.setId(entity.getId());
        return vo;
    }

    /**
     * 岗位修改数据
     *
     * @param ao 数据
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePost(PostUpdateAO ao) {
        Post post = super.getById(ao.getId());
        if (Objects.nonNull(post)) {
            if (!ao.getPostName().equals(post.getPostName()) && queryNameExist(ao.getPostName())) {
                throw new BusinessException("岗位名称已存在");
            }
            Post entity = new Post();
            BeanUtils.copyProperties(ao, entity);
            super.updateById(entity);
            deptPostService.addPostDept(entity.getId(), ao.getDeptIds());
            userPostService.addPostUser(entity.getId(), ao.getUserIds());
        }
    }

    /**
     * 岗位删除数据
     *
     * @param id 岗位ID
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deletePost(String id) {
        super.removeById(id);
        deptPostService.addPostDept(id, null);
        userPostService.addPostUser(id, null);
    }

    /**
     * 岗位批量删除数据
     *
     * @param ids 请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatchPost(List<String> ids) {
        super.removeByIds(ids);
        for (String id : ids) {
            deptPostService.addPostDept(id, null);
            userPostService.addPostUser(id, null);
        }
    }

    /**
     * 岗位导出数据
     *
     * @param ao     请求参数
     * @param stream 输出流
     */
    @Override
    public void exportPost(PostPageAO ao, ServletOutputStream stream) {
        ao.setSize(-1);
        List<PostVO> vos = queryPostPage(ao).getRecords();
        List<PostExcelVO> list = new ArrayList<>(vos.size());
        for (PostVO vo : vos) {
            PostExcelVO excelVo = new PostExcelVO();
            BeanUtils.copyProperties(vo, excelVo);
            list.add(excelVo);
        }

        ExcelWriter excelWriter = EasyExcelFactory.write(stream).build();
        excelWriter.write(list, EasyExcelFactory.writerSheet(NumberConstants.ZERO).head(PostExcelVO.class).build());
        excelWriter.finish();
    }

    /**
     * 岗位启用、停用
     *
     * @param ao 数据
     */
    @Override
    public void enablePost(PostEnabledAO ao) {
        this.lambdaUpdate().eq(Post::getId, ao.getId()).set(Post::getEnabled, ao.getEnabled()).update(new Post());
    }

    /**
     * 岗位下拉列表查询
     *
     * @param ao 请求参数
     * @return List<PostDropDownVO> 响应参数
     */
    @Override
    public List<PostDropDownVO> queryPostDropDown(PostDropDownAO ao) {
        return baseMapper.queryPostDropDown(ao);
    }

    /**
     * 查询岗位名称是否存在
     *
     * @param postName 岗位名称
     * @return boolean
     */
    private boolean queryNameExist(String postName) {
        return SqlHelper.retBool(this.lambdaQuery().eq(Post::getPostName, postName).count());
    }
}